import 'package:flutter/material.dart';
import 'package:flutter_harmonyos/userInfo.dart';
import 'package:flutter_harmonyos/userInfo2.dart';

import 'core/app_config.dart';
import 'core/gitcode_api.dart';

/// 区分搜索模式：用户 或 仓库。
enum QueryMode { user, repository }

void main() {
  runApp(const GitCodePocketToolApp());
}

class GitCodePocketToolApp extends StatelessWidget {
  const GitCodePocketToolApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GitCode 口袋工具',
      theme: ThemeData(
        colorSchemeSeed: Colors.indigo,
        useMaterial3: true,
        visualDensity: VisualDensity.standard,
      ),
      home: const GitCodePocketToolPage(),
    );
  }
}

class GitCodePocketToolPage extends StatefulWidget {
  const GitCodePocketToolPage({super.key});

  @override
  State<GitCodePocketToolPage> createState() => _GitCodePocketToolPageState();
}

//首页状态管理类
class _GitCodePocketToolPageState extends State<GitCodePocketToolPage> {
  _GitCodePocketToolPageState() {
    //初始化就设置默认的值，方便测试
    _tokenController.text = AppConfig.demoToken;
  }

  /// 输入框控制器、表单 key、API 客户端等 UI 层状态。
  final _keywordController = TextEditingController();
  final _tokenController = TextEditingController();
  final _formKey = GlobalKey<FormState>();
  final _client = GitCodeApiClient();

  /// API 实例：封装所有接口请求逻辑（搜索用户/仓库）

  QueryMode _mode = QueryMode.user;

  ///搜索结果
  List<GitCodeSearchUser> _userResults = const [];
  List<GitCodeRepository> _repoResults = const [];

  String? _errorMessage;
  bool _isLoading = false;
  bool _obscureToken = true;

  /// 生命周期方法：组件销毁时调用
  /// 释放输入框控制器资源，避免内存泄漏
  @override
  void dispose() {
    _keywordController.dispose();
    _tokenController.dispose();
    super.dispose();
  }

  /// 统一的搜索入口：根据模式调用不同接口，并处理通用的 Loading / Error 逻辑。
  Future<void> _performSearch() async {
    if (_isLoading) return;
    if (!_formKey.currentState!.validate()) return;

    FocusScope.of(context)
        .unfocus(); //取消当前上下文（Context）内所有焦点的核心方法，常用于关闭输入框软键盘、释放焦点资源等场景

    ///更新 UI 状态
    setState(() {
      _isLoading = true;
      _errorMessage = null;
      _userResults = const [];
      _repoResults = const [];
    });

    final token = _tokenController.text.trim();

    try {
      // 根据当前模式执行对应的 API 请求。
      if (_mode == QueryMode.user) {
        final users = await _client.searchUsers(
          keyword: _keywordController.text,
          personalToken: token,
          perPage: 8,
        );
        setState(() {
          ///只更新user值
          _userResults = users;
        });
      } else {
        final repos = await _client.searchRepositories(
          keyword: _keywordController.text,
          personalToken: token,
          perPage: 8,
        );
        setState(() {
          _repoResults = repos;
        });
      }
    } on GitCodeApiException catch (error) {
      setState(() {
        _errorMessage = error.message;
      });
    } catch (error) {
      setState(() {
        _errorMessage = '未知错误：$error';
      });
    } finally {
      if (mounted) {
        setState(() {
          _isLoading = false;
        });
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      //一个页面的模板root view 提供标准页面结构（导航栏、主体内容区）
      appBar: AppBar(
        //导航栏：显示应用标题
        title: const Text('GitCodejll 口袋工具'),
      ),
      // 主体内容区：
      body: SafeArea(
        //安全适配组件
        child: SingleChildScrollView(
          //单 child 滚动容器组件
          padding: const EdgeInsets.all(20),
          child: Column(
            // 垂直布局组件，用于将子组件按「从上到下」的顺序线性排列
            crossAxisAlignment: CrossAxisAlignment.start, //对齐方式
            children: [
              _buildIntro(), //构建介绍
              const SizedBox(height: 20), //占位20
              _buildFormCard(), //构建卡片
              const SizedBox(height: 20),
              _buildResultSection(), //构建返回的结果
            ],
          ),
        ),
      ),
    );
  }

  /// 构建页面介绍文本
  Widget _buildIntro() {
    return const Text(
      '输入关键字 + access token，立即查询 GitCode 用户或仓库（搜索接口需授权）。',
      style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500),
    );
  }

  /// 构建核心表单卡片
  Widget _buildFormCard() {
    return Card(
      //卡片式容器组件
      elevation: 0,
      clipBehavior: Clip.antiAlias, //该模式采用抗锯齿裁剪边缘，以实现更平滑的画面
      child: Padding(
        //包裹容器，主要是控制间距
        padding: const EdgeInsets.all(20),
        child: Form(
          key: _formKey,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              _buildModeSwitcher(), //模式切换
              const SizedBox(height: 12),
              TextFormField(
                //带表单功能的文本输入框组件
                controller: _keywordController,
                //输入控制器 用于读取输入值、设置默认值、清空输入、监听输入变化
                textInputAction: TextInputAction.search,
                //类型·
                decoration: const InputDecoration(
                  labelText: '搜索dd关键字',
                  hintText: '例如：iflytek / spark',
                  prefixIcon: Icon(Icons.search),
                ),
                validator: (value) {
                  //验证回调（表单核心）：返回 null 表示验证通过，返回字符串表示错误提示
                  if (value == null || value.trim().isEmpty) {
                    return '请输入关键字';
                  }
                  return null;
                },
                onFieldSubmitted: (_) =>
                    _performSearch(), //输入框回车回调：用户按下键盘回车时触发（如搜索框回车提交）。
              ),
              const SizedBox(height: 12),
              TextFormField(
                //token 校验布局的实现
                controller: _tokenController,
                decoration: InputDecoration(
                  labelText: 'Access Token',
                  hintText: 'GitCode 个人设置 > Access Token',
                  prefixIcon: const Icon(Icons.vpn_key_outlined), //前面的图标
                  suffixIcon: IconButton(
                    //后面的图标
                    icon: Icon(
                      _obscureToken
                          ? Icons.visibility_off_outlined
                          : Icons.visibility_outlined,
                    ),
                    onPressed: () {
                      setState(() {
                        _obscureToken = !_obscureToken;
                      });
                    },
                  ),
                ),
                obscureText: _obscureToken, //是否隐藏输入内容（true 时显示为圆点）
                validator: (value) {
                  if (value == null || value.trim().isEmpty) {
                    return '搜索接口需提供 access token';
                  }
                  return null;
                },
              ),
              const SizedBox(height: 16),
              FilledButton.icon(
                //点击事件：加载中禁用按钮（onPressed 为 null），否则触发搜索
                onPressed: _isLoading ? null : _performSearch,
                icon: _isLoading
                    ? const SizedBox(
                        width: 18,
                        height: 18,
                        child: CircularProgressIndicator(strokeWidth: 2),
                      )
                    : const Icon(Icons.play_arrow_rounded),
                label: Text(_isLoading ? '查询中...' : '查询'),
              ),
            ],
          ),
        ),
      ),
    );
  }

  //搜索结果的实现
  // 根据状态（加载中/错误/无结果/有结果）显示不同内容
  Widget _buildResultSection() {
    if (_isLoading) {
      return const Center(child: CircularProgressIndicator());
    }

    if (_errorMessage != null) {
      // 统一信息展示组件，既可以显示错误也能展示提示。
      return _InfoBanner(
        icon: Icons.error_outline,
        background: Colors.red.withValues(alpha: 0.08),
        textColor: Colors.red.shade700,
        message: _errorMessage!,
      );
    }

    if (_mode == QueryMode.user) {
      return _buildUserResults();
    }
    return _buildRepositoryResults();
  }

// 构建搜索模式切换器（用户/仓库）
  Widget _buildModeSwitcher() {
    return SegmentedButton<QueryMode>(
      segments: const [
        ButtonSegment(
          value: QueryMode.user,
          icon: Icon(Icons.person_outline),
          label: Text('用户'),
        ),
        ButtonSegment(
          value: QueryMode.repository,
          icon: Icon(Icons.bookmark_outline),
          label: Text('仓库'),
        ),
      ],
      selected: <QueryMode>{_mode},
      onSelectionChanged: (selection) {
        final next = selection.first;
        if (next != _mode) {
          // 切换模式时及时清理旧结果，避免跨模式串数据。
          setState(() {
            _mode = next;
            _errorMessage = null;
            _userResults = const [];
            _repoResults = const [];
          });
        }
      },
    );
  }

// 构建用户搜索结果列表
  Widget _buildUserResults() {
    if (_userResults.isEmpty) {
      return const _InfoBanner(
        icon: Icons.info_outline,
        background: Color(0xFFEFF4FF),
        textColor: Color(0xFF1A237E),
        message: '暂无数据，输入关键字并点击“查询”试试。',
      );
    }

    return Column(
      children: _userResults.map(_UserTile.new).toList(),
    );
  }

// 构建仓库搜索结果列表
  Widget _buildRepositoryResults() {
    if (_repoResults.isEmpty) {
      return const _InfoBanner(
        icon: Icons.info_outline,
        background: Color(0xFFEFF4FF),
        textColor: Color(0xFF1A237E),
        message: '还没有结果，输入关键字并点击查询即可获取仓库列表。',
      );
    }
    //有结果：将仓库列表转为 _RepoTile 组件列表（垂直排列）
    return Column(
      children: _repoResults.map(_RepoTile.new).toList(),
    );
  }
}

// 通用信息横幅组件
class _InfoBanner extends StatelessWidget {
  const _InfoBanner({
    required this.icon,
    required this.background,
    required this.textColor,
    required this.message,
  });

  final IconData icon;
  final Color background;
  final Color textColor;
  final String message;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity, // 宽度占满父容器
      padding: const EdgeInsets.all(16), // 内边距：16px
      decoration: BoxDecoration(
        color: background,
        borderRadius: BorderRadius.circular(12),
      ),
      child: Row(
        // 水平布局：图标 + 文本
        crossAxisAlignment: CrossAxisAlignment.start, // 垂直对齐：顶部对齐
        children: [
          Icon(icon, color: textColor),
          const SizedBox(width: 12),
          Expanded(
            //文本扩展：占满剩余宽度（避免文本溢出）
            child: Text(
              message,
              //文本样式：继承主题的 bodyMedium 样式，覆盖文本色
              style: Theme.of(context)
                  .textTheme
                  .bodyMedium
                  ?.copyWith(color: textColor),
            ),
          ),
        ],
      ),
    );
  }
}

/// 用户结果项组件
class _UserTile extends StatelessWidget {
  const _UserTile(this.user); // 构造函数：接收单个用户数据

  final GitCodeSearchUser user;

  @override
  @override
  Widget build(BuildContext context) {
    // 标题：优先显示用户名（name），无则显示登录名（login）
    final title = user.name?.isNotEmpty == true ? user.name! : user.login;
    // 副标题部分：登录名 + 注册时间（拼接成「@login · 注册时间」格式）
    final subtitleParts = <String>[
      '@${user.login}', // 登录名（带 @ 符号，模仿社交平台风格）
      if (user.createdAt != null) '注册 ${user.createdAt}', // 注册时间（非空才显示）
    ];

    return Card(
      // 结果项卡片：无阴影、底部间距 12px
      elevation: 0,
      margin: const EdgeInsets.only(bottom: 12), // 底部间距：分隔多个结果项
      child: Builder(builder: (innerContext){
        return ListTile(
          // ListTile：Material 标准列表项组件（图标+标题+副标题）
          onTap: () {
            var userName = '${user.name}';
            print('jll 点击了：$userName');
            ScaffoldMessenger.of(innerContext).showSnackBar(
              SnackBar(
                content:  Text('点击了：$userName'), // 提示文本
                duration: const Duration(seconds: 2), // 显示时长（默认 4 秒）
                backgroundColor: Colors.grey[700], // 背景色
                behavior: SnackBarBehavior.floating, // 悬浮样式（默认固定底部） 
                margin:  EdgeInsets.only(left: 10,top: 100,right: 10,bottom: 100), // 距离底部间距
              ),
            );
            //方案一
            // Navigator.push(
            //     context,
            //     MaterialPageRoute<void>(
            //       builder: (context) =>  UserInfo(userInfoBean:UserInfoBean(userId: '123', userName: "9527")),
            //     ),
            //   );
            // 方案二
            Navigator.push(
                context,
                MaterialPageRoute<void>(
                  builder: (context) =>  UserInfo2(),
                  settings: RouteSettings(arguments: user),
                ),
              );
          },
          onLongPress: () {
            print('jll 长按了：${user.name}');
          },
          leading: CircleAvatar(
            // 左侧头像：圆形头像展示用户头像
            backgroundImage: NetworkImage(user.avatarUrl), // 网络图片：用户头像 URL
            onBackgroundImageError: (_, __) {}, // 图片加载失败回调：空实现（避免闪退）
          ),
          title: Text(title, style: const TextStyle(fontWeight: FontWeight.w600)),
          // 标题：用户名（粗体）
          subtitle: Column(
            // 副标题：垂直排列多个文本（登录名、注册时间、个人主页 URL）
            crossAxisAlignment: CrossAxisAlignment.start, // 左对齐
            children: [
              // 登录名 + 注册时间
              Text(
                subtitleParts.join(' · '), // 用「·」分隔多个部分
                style: const TextStyle(fontSize: 12), // 小字体（12号）
              ),
              // 个人主页 URL（非空才显示）
              if (user.htmlUrl != null)
                Text(
                  user.htmlUrl!,
                  style: const TextStyle(
                      fontSize: 12, color: Colors.blue), // 蓝色文本（模仿链接样式）
                ),
            ],
          ),
        );
      }),
    );
  }
}

// 仓库结果项组件
class _RepoTile extends StatelessWidget {
  const _RepoTile(this.repo); // 构造函数：接收单个仓库数据

  final GitCodeRepository repo; // 仓库数据模型

  @override
  Widget build(BuildContext context) {
    return Card(
      // 结果项卡片：无阴影、底部间距 12px
      elevation: 0,
      margin: const EdgeInsets.only(bottom: 12),
      child: ListTile(
        // ListTile：标准列表项布局
        leading: const Icon(Icons.folder_outlined),
        // 左侧图标：文件夹图标（代表仓库）
        title: Text(repo.fullName,
            style: const TextStyle(fontWeight: FontWeight.w600)),
        // 标题：仓库全名（用户名/仓库名）
        subtitle: Column(
          // 副标题：垂直排列多个信息（描述、统计指标、更新时间、仓库 URL）
          crossAxisAlignment: CrossAxisAlignment.start, // 左对齐
          children: [
            // 仓库描述（非空且不为空字符串才显示）
            if (repo.description?.isNotEmpty == true)
              Padding(
                padding: const EdgeInsets.only(bottom: 4), // 底部间距：与下方统计指标分隔
                child: Text(
                  repo.description!,
                  maxLines: 2, // 最大行数：2行（避免描述过长占用过多空间）
                  overflow: TextOverflow.ellipsis, // 溢出处理：省略号（...）
                ),
              ),
            // 统计指标：语言、Star 数、Fork 数（用 Chip 组件展示，横向排列）
            Wrap(
              spacing: 8, // 水平间距：Chip 之间 8px
              runSpacing: 4, // 垂直间距：多行时 4px
              children: [
                // 编程语言（非空才显示）
                if (repo.language != null)
                  _StatChip(label: '语言', valueLabel: repo.language),
                // Star 数
                _StatChip(label: 'Star', value: repo.stars),
                // Fork 数
                _StatChip(label: 'Fork', value: repo.forks),
              ],
            ),
            const SizedBox(height: 4), // 垂直间距：分隔统计指标和更新时间
            // 最后更新时间（非空则显示，否则显示「-」）
            Text(
              '更新 ${repo.updatedAt ?? '-'}',
              style: const TextStyle(fontSize: 12), // 小字体
            ),
            // 仓库 Web 地址（蓝色文本，模仿链接样式）
            Text(
              repo.webUrl,
              style: const TextStyle(fontSize: 12, color: Colors.blue),
            ),
          ],
        ),
      ),
    );
  }
}

// 统计指标 Chip 组件
class _StatChip extends StatelessWidget {
  const _StatChip({
    required this.label, // 指标标签（如「Star」「语言」）
    this.value, // 数值类型指标（如 Star 数、Fork 数）
    this.valueLabel, // 文本类型指标（如编程语言名称）
  });

  final String label;
  final int? value; // 数值型指标（二选一：value 或 valueLabel）
  final String? valueLabel; // 文本型指标

  @override
  Widget build(BuildContext context) {
    final textTheme = Theme.of(context).textTheme; // 获取主题文本样式
    // 显示文本：优先用 valueLabel（文本型），否则用 value（数值型，默认 0）
    final displayText = valueLabel ?? (value ?? 0).toString();

    return Chip(
      // Chip 组件：Material 标准标签组件（圆角、浅背景）
      label: Column(
        // 垂直布局：指标值 + 指标标签
        mainAxisSize: MainAxisSize.min, // 最小主轴尺寸（避免占用过多空间）
        children: [
          // 指标值（大号字体，突出显示）
          Text(
            displayText,
            style: textTheme.titleMedium,
          ),
          // 指标标签（小号字体）
          Text(label, style: textTheme.bodySmall),
        ],
      ),
    );
  }
}
